
#ifndef __MY_SERVER_COPY_HPP__
#define __MY_SERVER_COPY_HPP__

#include <vector>
#include <string>
#include <algorithm> 
#include <iostream>

#include <cassert>






//缓冲区模块
#define BUFFER_DEFAULT_SIZE 6

class Buffer{
    private:
        std::vector<char> _buf; //缓冲区 
        char* _read_position; //读取位置的 指针
        char* _write_position; // 写入位置的 指针 
    private:
        //确保可读空间足够
        void ensure_write_space(uint64_t len){
            //尾部空间足够
            if(len <= get_back_size()) return;

            uint64_t size = readable_size();
            //总体空间足够
            if(len <= get_total_size() ){
                //移动数据
                std::copy(get_read_position(), get_write_position(), get_begin_position());
                _read_position = get_begin_position();
                _write_position = _read_position + size; 
            }
            //扩容了
            _buf.resize(get_write_position() - get_begin_position() + len * 2);
            //更新一下read / write 的指针, 异地扩容
            _read_position = get_begin_position();
            _write_position = _read_position + size;
        }

    public: 
        Buffer():_buf(BUFFER_DEFAULT_SIZE), _read_position(&(_buf[0])), _write_position(&(_buf[0])){ }
        char* get_begin_position(){return &(_buf[0]);}
        char* get_end_position(){return &(_buf[_buf.size()-1]);}
        // 获取读写位置的指针
        char* get_read_position(){ return _read_position;}
        char* get_write_position(){ return _write_position;}

        //获取前后剩余空间大小 / 总空间大小
        uint64_t get_front_size(){ return (_read_position - get_begin_position()); }
        uint64_t get_back_size(){ return (get_end_position() - _write_position) + 1; }
        uint64_t get_total_size(){ return ( get_front_size() +  get_back_size());}

        //可读数据大小
        uint64_t readable_size(){ return _write_position - _read_position;}

        //读取数据 , 返回读取的数据个数 len 是最大读取个数
        void read_buf(char* buf, uint64_t len){ assert(len <= readable_size()); std::copy(get_read_position(), get_read_position() + len, buf);}
        void write_buf(const char* buf, uint64_t len){
            ensure_write_space(len);
            std::copy(buf, buf + len, _write_position); 
        }

        void read_buf_move(char* buf, uint64_t len){read_buf(buf, len); read_position_move(len);}
        void write_buf_move(const char* buf, uint64_t len){write_buf(buf, len); write_position_move(len);}
        //移动read_position / write_position 
        void read_position_move(uint64_t len){ assert(len <= readable_size());  _read_position += len; }
        void write_position_move(uint64_t len){ assert(len <= get_back_size()); _write_position += len; }


        void print(){
            std::cout<< "[" << _buf.size()<<":"<<readable_size() << "] : " ;
            for(char* it = _read_position ; it<_write_position; it++){
                std:: cout<< " "<< *it;
            }
            std::cout<<std::endl;
        }
};

#endif